template<class DataType>
RegGrammatica<DataType>::RegGrammatica()
{
}

template<class DataType>
RegGrammatica<DataType>::RegGrammatica(list<DataType> helpSymbols, list<char> alphabet, list<ProductionRule <DataType> > productionRules, DataType startSymbol)
{
	this->nonTerminals = helpSymbols;
	this->alphabet = alphabet;
	this->productionRules = productionRules;
	this->startSymbol = startSymbol;
}

template<class DataType>
RegGrammatica<DataType>::RegGrammatica(list<ProductionRule<DataType> > productionRules, DataType startSymbol)
{
	this->productionRules = productionRules;
	this->startSymbol = startSymbol;
}

template<class DataType>
RegGrammatica<DataType>::~RegGrammatica()
{
}

template<class DataType>
void RegGrammatica<DataType>::prodLine(ostream &os, const list<ProductionRule<DataType> >& allRules)
{		//print alle productieregels
		list<ProductionRule<DataType> > productionRules;
		for (list<ProductionRule<DataType> >::const_iterator rules = allRules.begin(); rules != allRules.end(); rules++) {
			os << *rules <<endl;
		}

}

template <class DataType> 
list<DataType> RegGrammatica <DataType>::getLanguage(int maxSteps)
{
	list<DataType> language;						//list met de gegenereerde woorden
	generateWords(maxSteps, startSymbol, "", language);	//recursieve functie aanroep	
	return sort(language);							//return de list met gegenereerde woorden
 }

template <class DataType> 
void RegGrammatica <DataType>::generateWords(unsigned int maxSteps, const DataType & nonTerminal, const string & word, list<DataType>& language)
{
	list< ProductionRule < DataType > >::iterator it;	
	if (word.size()<maxSteps)									//zolang word niet groter is als maxSteps
	{
		for(it = productionRules.begin(); it != productionRules.end(); it++)				//itereren over de productieregels
		{
			ProductionRule < DataType > nextRule = *it;
			if (nonTerminal == nextRule.getLeftNonTerminal())
			{
				if (nextRule.getRightTerminal()== '$'){			//als de rechter teminal een Epsilon is
					language.push_back("$");
				}
				else
				{
					string resultWord = string(word + nextRule.getRightTerminal());	//terminal van regel toevoegen
					if (nextRule.getIfEnd())					//als er een terminal is gevonden		
					{											//wordt het wordt toegevoegd aan de list
						language.push_back(resultWord);
					}
					else										//recursie
					{
						generateWords(maxSteps, nextRule.getRightNonTerminal(), resultWord, language);
					}
				}
			}
		}
	}
}

template<class DataType>
list<DataType> RegGrammatica<DataType>::getNonTerminals()
{
	return this->nonTerminals;
}

template<class DataType>
list<char> RegGrammatica<DataType>::getAlphabet()
{
	return this->alphabet;
}

template<class DataType>
list<ProductionRule<DataType> > RegGrammatica<DataType>::getProductionRules()
{
	return this->productionRules;
}

template<class DataType>
DataType RegGrammatica<DataType>::getStartSymbol()
{
	return this->startSymbol;
}

template<class DataType>
void RegGrammatica<DataType>::printLanguage(int count)
{
	list<string> tempList = getLanguage(count);
	for(list<string>::iterator j = tempList.begin(); j != tempList.end(); j++)
	{
		//if(j == tempList.begin())
		//{
			cout <<*j << ", ";
		//}
		//else
		//{
		//	cout << "                 " << "[" << *j << "]" << endl;
		//}
	}
	cout <<endl;

}

template<class DataType>
void RegGrammatica<DataType>::printProdRules()
{
	cout << "4-Tupel        : G = (N, Alfabet, P, S)" <<endl<<endl;

	cout << "N              : { ";
	
	for(list<string>::iterator n = nonTerminals.begin(); n != nonTerminals.end(); n++)
	{
		if(n == nonTerminals.end())
		{
			cout << *n;
		}
		else 
		{
		cout << *n << ", ";
		}
	}
	cout << " }" << endl;
	cout << "ALPHABET       : { ";
	for(list<char>::iterator a = alphabet.begin(); a != alphabet.end(); a++)
	{
		if(a == alphabet.end())
		{
			cout << *a;
		}
		else 
		{
		cout << *a << ", ";
		}
	}
	cout << " }" << endl;


	for(list<ProductionRule<string> >::iterator i = productionRules.begin(); i != productionRules.end(); i++)
	{
		if(i == productionRules.begin())
		{
			cout << "Productionrules: " << *i << endl;
		}
		else
		{
			cout << "		 " << *i << endl;
		}
	}
	cout << "Startsymbol    : " << startSymbol<<endl;
}

template <class DataType>
list<string> RegGrammatica<DataType>::sort(list<string> &sourceList)
{
	list<string> resultList;
	list<string>::const_iterator i, j;
	sourceList.sort();
	sourceList.unique();
	for(i = sourceList.begin(); i != sourceList.end(); i++)
	{
		if(resultList.empty())
		{
			resultList.push_front(*i);
		}
		else
		{
			for(j = resultList.begin(); j != resultList.end(); j++)
			{
				if(j->length() > i->length())
				{
					break;
				}
			}
			resultList.insert(j, *i);
		}
	}
	return resultList;
}